<?php
/**
 * 项目管理模块
 * User: lyc
 * Date: 2016/11/18
 * Time: 10:56
 */

class AdminInvestService extends BaseService
{
    private static $self = NULL;
    private $mItem = NULL;
    private $mInvest = NULL;
    private $mUserAward = NULL;
    private $mDealMarket = NULL;
    private $mUserTicket            = NULL;
    private $mRefundItemPlan        = NULL;
    private $mRefundPlan            = NULL;
    private $mDealUnfreeze          = NULL;

    static public function instance()
    {
        if (self::$self == NULL) {
            self::$self = new self;
        }
        return self::$self;
    }
    public function __construct()
    {
        $this->mItem = new Involved_ItemModel();
        $this->mInvest = new Involved_InvestModel();
        $this->mUserAward = new Involved_UserAwardModel();
        $this->mDealMarket = new Involved_DealMarketModel();
        $this->mUserTicket             = new Involved_UserTicketModel();
        $this->mRefundItemPlan         = new Involved_RefundItemPlanModel();
        $this->mRefundPlan             = new Involved_RefundPlanModel();
        $this->mDealUnfreeze           = new Involved_DealUnfreezeModel();
    }
    public function FindItem($itemWhere){
        return  $this->mItem->FindItem($itemWhere);
    }
    public function FindInvest($investWhere){
        return  $this->mInvest->FindInvest($investWhere);
    }
    public function FindInvestSubsidy($investWhere){
        return  $this->mInvest->FindInvestSubsidy($investWhere);
    }

    /**
     * @param $itemID
     * @return int
     * @throws Exception
     * 生成还款计划
     */
    public function PlanConfirm($itemID){
        // 查找待放款项目
        $where = [
            'auto_id' => $itemID,
            'status'  => 'FULLSCALE',
        ];
        $item = DB::table('item')->where($where)->first();

        if (!$item)
        {
            throw new Exception('不存在此项目, 请联系管理员', 400);
        }
        // 获取投资人
        $investWhere = [
            'item_id' => $item->auto_id,
            'status'  => 'SUCCESS',
        ];

        $invests = DB::table('invest')->select('trade_num','user_id','ticket_id','amount','add_time')->where($investWhere)->get();

        if (!$invests)
        {
            throw new Exception('此项目不存在投资用户, 请联系管理员', 400);
        }

        set_time_limit(60);

        // 放款明细(接口使用数据)
        $investTrade = [];
        // 用户投资金额列表(如果有多笔投资将合并)
        $refundPlanList = [];

        foreach ($invests as $key => &$value)
        {
            // 放款明细
            $investTrade[] = [
                'amount'    => $value->amount/100,
                'trade_num' => $value->trade_num,
            ];
            // 用户投资金额列表
            if (isset($refundPlanList[$value->user_id]))
            {
                $refundPlanList[$value->user_id]->amount += $value->amount;
            }
            else
            {
                $refundPlanList[$value->user_id] = $value;
            }
            // 默认加息金额为
            $refundPlanList[$value->user_id]->amount_ticket = 0;
            // 默认站岗利息金额为
            $refundPlanList[$value->user_id]->subsidy = 0;
            // 默认站岗天数为
            $refundPlanList[$value->user_id]->subsidy_day = 0;
        }
        // 计息系数
        $arrange = $item->deadline/365;
        //$arrange = ($item['is_byday'] == 1) ? ($item['deadline']/365) : ($item['deadline']/12);

        // 计算加息券利息
        foreach ($invests as $key => &$value)
        {
            // 如果使用加息券
            if ($value->ticket_id == 0)continue ;
//                $subsidy_day = floor(($item->repaying_time-$value->add_time)/86400);
//                if($subsidy_day>=1){
//                    $subsidy = floor($value->amount*$item->rate_loaner/100*$subsidy_day/365);
//                }else{
//                    $subsidy = 0;
//                }
//                DB::table('invest')->where('user_id', $value->user_id)->update(array('subsidy_day' => $subsidy_day,'subsidy'=>$subsidy));
//                $refundPlanList[$value->user_id]->subsidy       +=   floor($value->amount*$item->rate_loaner/100*$arrange*$subsidy_day);

                // 获取加息券
                $ticket = $this->mUserTicket->FindTicket($value->ticket_id);
                if (!$ticket) continue ;
//                $subsidy_day = floor(($item->repaying_time-$value->add_time)/86400);
//                if($subsidy_day>=1){
//                    $subsidy = floor($value->amount*($ticket->rate/100+$item->rate_loaner/100)*$subsidy_day/365);
//                }else{
//                    $subsidy = 0;
//                }
//                //站岗利息入库
//                DB::table('invest')->where('user_id', $value->user_id)->update(array('subsidy_day' => $subsidy_day,'subsidy'=>$subsidy));
//                $refundPlanList[$value->user_id]->subsidy       +=   floor($value->amount*$ticket->rate/100*$subsidy_day+$value->amount*$item->rate_loaner*$subsidy_day);
                $refundPlanList[$value->user_id]->amount_ticket +=   floor($value->amount*$ticket->rate/100*$arrange);
            }






        // 创建订单号
        $tradeNumber = StatusEnum::buildNumber('L_ITEM_CONFIRM');

        if (!$tradeNumber)
        {
            throw new Exception('创建请求订单号错误, 请联系管理员', 400);
        }

       // $lazyItem = \moon\middleware('lazycat\\Item');

//        $result = $lazyItem->confirm(
//        // 放款确认订单号
//            $tradeNumber,
//            // 标的编号
//            $item['number'],
//            // 放款明细
//            $investTrade
//        );

        $result['status'] =200;
        if ($result['status'] != 200)
        {
            throw new Exception('放款出现错误, 保留此错误, 并立即联系管理员<br>'.$result['data']['description'], $result['status']);
        }

        // 记录放款确认操作
        //helper('item\\Item::confirm', $item['auto_id'], 'READY_CONFIRM', $tradeNumber, json_encode($result));

        // 还款计划
        // 投资用户还款计划
        $userPlan = [];
        // 项目还款计划
        $itemPlan = [];

        // 按天计息
            $startTime  = time();
            $refundTime = strtotime("+{$item->deadline} day");

            // 标的还款计划
            $itemPlan = [
                // 标的ID
                'item_id'        => $item->auto_id,
                // 期数, 按天计息, 一次性还款
                'stage'          => 1,
                // 还款开始时间
                'start_time'     => $startTime,
                // 应还款时间
                'refund_time'    => $refundTime,
                // 还款本金
                'amount_capital' => $item->amount,
                // 还给投资人金额
                'amount_loaner_accrual'  => ceil($item->amount*($item->rate_loaner/100)/365*$item->deadline),
                // 实际还款金额
                'amount_reality_accrual' => ceil($item->amount*($item->rate_debtor/100)/365*$item->deadline),
                // 默认状态
                'status'         => 'NONE'
            ];

            // 用户回款计划
            foreach ($refundPlanList as $key => $value)
            {
                // 用户每月应收利息
                $userAccrual = floor($value->amount*($item->rate_loaner/100)/365*$item->deadline);

                $userPlan[]  = [
                    // 用户ID
                    'user_id'        => $value->user_id,
                    // 标的ID
                    'item_id'        => $item->auto_id,
                    // 标的号码
                    'item_number'    => $item->number,
                    // 按天计息, 一次性还款
                    'stage'          => 1,
                    // 还款开始时间
                    'start_time'     => $startTime,
                    // 应还款时间
                    'refund_time'    => $refundTime,
                    // 还款本金
                    'amount_capital' => $value->amount,
                    // 还款利息
                    'amount_accrual' => $userAccrual,
                    // 加息金额
                    'amount_ticket'  => $value->amount_ticket,
                    //站岗利息
                    'amount_subsidy' => $value->subsidy
                ];
            }



        // 保存还款计划

        $itemPlanResult = $this->mRefundItemPlan->insert($itemPlan);

        if ($itemPlanResult)
        {
            $this->mRefundPlan->insert($userPlan);
        }
        else
        {
            throw new Exception('生成还款计划失败，请立即联系管理员', 502);
        }

        // 解冻投资金额
        foreach ($refundPlanList as $key => $value)
        {
            $this->unfreeze($value->user_id,'INVEST',$value->amount);
        }

        // 修改项目状态为还款中
        $saveItemTradeNumber = StatusEnum::buildNumber('L_ITEM_REPAYING');

        if (!$saveItemTradeNumber)
        {
            throw new Exception('还款计划已生成，创建还款中状态请求订单号错误, 请立即联系管理员', 400);
        }

//        $result = $lazyItem->repaying(
//        // 回款中项目操作订单号
//            $saveItemTradeNumber,
//            // 标的编号
//            $item['number']
//        // 放款明细
//        );
        $result['status'] = 200;
        if ($result['status'] != 200)
        {
            throw new Exception('更新状态出现错误， 请截图保留， 并立即联系管理员<br>'.$result['data']['description'], $result['status']);
        }

        $result = DB::table('item')->where('auto_id', $item->auto_id)->update(array('status' => 'REPAYING'));

        if (!$result)
        {
            throw new Exception('更新状态出现错误， 请截图保留，并立即联系管理员<br>本地更新项目状态失败', 502);
        }

        return 200;

    }

    /**
     * 冻结金额解冻
     */
    public function unfreeze($userid, $detail, $amount = 0)
    {
        if (!$userid || !$detail)
        {
            throw new Exception('ERR', 400);
        }

//        $fundTable   = table('user\\Fund');
//        $recordTable = table('deal\\Unfreeze');

        $userFund = DB::table('user_fund')->select('user_id','money_freeze')->where('user_id', $userid)->first();
        $result   = DB::table('user_fund')->where('user_id', $userid)->decrement('money_freeze', $amount);

        if (!$result)
        {
            throw new Exception('ERR_UPDATE', 502);
        }

        $record = [
            'user_id'       => $userid,
            'amount'        => $amount,
            'update_before' => $userFund->money_freeze,
            'update_after'  => $userFund->money_freeze - $amount,
            'detail'        => $detail,
            'add_time'      => time(),
        ];

        $addState = $this->mDealUnfreeze->insert($record);

        return $addState ? 200 : 502;
    }


    /**
     * 确认还款
     */
    public function ConfirmIng($itemid){
        $whereItem = [
            'auto_id' => $itemid,
            'status'  => 'REPAYING',
        ];

        $item = DB::table('item')->where($whereItem)->first();

        if (!$item)
        {
            throw new Exception('不存在需要还款的项目', 404);
        }

        // 是否存在准备还款计划
        $planWhere = [
            'item_id' => $item['auto_id'],
            'status'  => 'READY',
        ];
        $itemPlan  = DB::table('refund_item_plan')->where($planWhere)->first();

        if (!$itemPlan)
        {
            throw new Exception('不存在已还款的预处理计划', 404);
        }

        set_time_limit(30);

        // 投资人还款计划
        $userPlanWhere = [
            'item_id' => $item['auto_id'],
            'stage'   => $itemPlan['stage'],
        ];
        $userPlan = DB::table('refund_plan')->where($userPlanWhere)->first();

        // 用户回款明细
        $refundPreList = [];
        // 用户回款总利息
        $refundTotalAmount = 0;

        foreach ($userPlan as $key => $value)
        {
            $refundAmount = ($value->amount_capital+$value->amount_accrual)/100;
            $refundPreList[] = [
                // 用户ID
                'user_id' => $value->user_id,
                // 回款本息
                'amount'  => $refundAmount,
                // 回款利息
                'accrual' => $value->amount_accrual/100,
            ];
            $refundTotalAmount += $value->amount_accrual;
        }
        // 平台佣金 = 借款方实际还款利息 - 应还用户总利息
        $commission = ($itemPlan->amount_reality_accrual - $refundTotalAmount)/100;

        if ($commission <= 0)
        {
            throw new Exception('项目佣金小于或等于 0 元，请联系管理员', 400);
        }

        // 确认还款操作
        $tradeNumber = StatusEnum::buildNumber('L_REFUND_CONFIRM');

//        $itemLazy = \moon\middleware('lazycat\\Item');
//        $result   = $itemLazy->refund(
//        // 请求流水号
//            $tradeNum,
//            // 预处理流水号
//            $itemPlan['trade_num'],
//            // 标的编号
//            $item['number'],
//            // 回款明细
//            $refundPreList,
//            // 平台佣金
//            $commission
//        );

        $result['status'] = 200;
        if ($result['status'] != 200)
        {
            throw new Exception('出现错误, 请截图保留, 并立即联系管理员<br>'.json_encode($result, JSON_UNESCAPED_UNICODE), $result['status']);
        }

        // 默认回款利息
        $refundDetail = 'REFUND_ACC';


            // 更新项目为已完成
            DB::table('item')->where('auto_id', $item->auto_id)->update(array('status' => 'FINISH'));
            $refundDetail = 'REFUND';

        $userPlanIds = [];
        foreach ($userPlan as $key => $value)
        {
            $totalAmount = ($value->amount_capital+$value->amount_accrual);
            // 还款成功, 资金增减
            $result = DealService::instance()->carry(
            // 用户ID
                $value->user_id,
                // 操作总资金
                $totalAmount,
                // 事件ID
                $value->auto_id,
                // 交易类型:回款
                'IN_REFUND',
                // 交易资金明细
                ['MONEY_RETURN' => $totalAmount],
                // 业务说明
                $refundDetail
            );

            $userPlanIds[] = $value->auto_id;
        }

        // 更新用户回款计划状态
        $UPState =  DB::table('refund_plan')->whereIn('auto_id', $userPlanIds)->update(array('status' => '1'));

        // 更新项目还款计划状态
        $UIState = DB::table('refund_plan')->where('auto_id', $itemPlan->auto_id)->update(array('status' => 'SUCCESS'));


        if (!$UPState || !$UIState)
        {
            throw new Exception('还款计划状态修改失败，请联系管理员', 502);
        }

        // 发放加息利息
        $ticketDetail = [];
        foreach ($userPlan as $key => $value)
        {
            if ($value->amount_ticket > 0)
            {
                $ticketDetail[] = [
                    'user_id'  => $value->user_id,
                    'amount'   => $value->amount_ticket,
                    'event_id' => $value->auto_id,
                ];
            }
        }

        if ($ticketDetail)
        {
            $ticketResult = $this->ticket('TICKET',$ticketDetail);
        }

        if ($ticketResult != 200)
        {
            throw new Exception('发放加息利息失败，， 请截图保留, 并立即联系管理员<br>'.json_encode($ticketResult, JSON_UNESCAPED_UNICODE), $ticketResult['status']);
        }

        return 200;
    }


    /**
     * 发放加息券利息
     */
    public function ticket($type, $data)
    {
        if (!array_key_exists($type,ItemEnum::GrantType()))
        {
            throw new Exception('交易类型不存在', 400);
        }

        // 订单号
        $tradeNumber = StatusEnum::buildNumber('L_PF_TICKET');

        if (!$tradeNumber)
        {
            throw new Exception('订单号码创建失败', 500);
        }

        // 发放营销款操作, 并记录订单明细
        $result = self::carry($type, $tradeNumber, $data);

        $result = 200;
        if ($result['status'] != 200)
        {
            return $result;
        }

        $success = [];

        // 账户资金操作
        foreach ($data as $key => $value)
        {
            // 余额增加
            $result = DealService::instance()->carry(
            // 用户ID
                $value['user_id'],
                // 操作总资金
                $value['amount'],
                // 事件ID
                $value['event_id'],
                // 交易类型:加息券收益
                'IN_TICKET',
                // 交易资金明细
                ['MONEY_RETURN' => $value['amount']],
                // 业务说明:加息券收益
                'TICKET'
            );

            // 记录操作状态
            if ($result['status'] == 200)
            {
                $success[] = $value['user_id'];
            }
        }

        return $success ? 200 : 502;
    }


    private static function carry($type, $tradeNum, $data)
    {
        // 发放明细
        $details = [];
        // 发放总金额
        $totalAmount = 0;

        foreach ($data as $key => $value)
        {
            $details[] = [
                'platformUserNo' => $value['user_id'],
                'amount'         => $value['amount']/100,
                'customDefine'   => $value['params']?$value['params']:'',
            ];
            $totalAmount += $value['amount'];
        }

        // 向用户账户发放营销款
//        $pfLazy = \moon\middleware('lazycat\\Platform');
//        $result = $pfLazy->marketing_direct($tradeNum, $details);

        $result['status'] = 200;
        if ($result['status'] != 200)
        {
            return $result;
        }

        // 添加营销款发放记录
        $record = [
            'trade_num' => $tradeNum,
            'type'      => $type,
            'amount'    => $totalAmount,
            'data'      => json_encode($data),
            'add_time'  => time(),
        ];

        $addstate =  DB::table('deal_market')->insert($record);

        return $result;
    }


    public function updateAward($auto_id){
        return  $this->mItem->updateAward($auto_id);

    }
    public function SelectUserAward($awardids){
        return  $this->mUserAward->SelectUserAward($awardids);
    }
    public function AwardInsert($record){
        return $this->mDealMarket->insert($record);

    }
    public function updateAwardStatus($awardids){
        return  $this->mUserAward->updateAwardStatus($awardids);
    }
    public function FindItemSubsidy($item_id){
        return  $this->mItem->FindItemSubsidy($item_id);

    }
    public function updateSubsidy($auto_id){
        return  $this->mItem->updateSubsidy($auto_id);

    }
    public function updateSubsidyAll($auto_id,$value){
        return  $this->mInvest->updateSubsidyAll($auto_id,$value);

    }

}